home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2004 #2 / Amiga Plus CD - 2004 - No. 02.iso / AmigaPlus / Tools / Development / AmigaTalk / general / ComputedValue.st < prev    next >
Encoding:
Text File  |  2004-01-31  |  3.5 KB  |  105 lines

  1. " -------------------------------------------------------------------
  2.   ComputedValue is an abstract class that represents a computation 
  3.   that propagates changes to dependents.  It caches the result of the 
  4.   computation.  Kinds of ComputedValues can not respond to the message 
  5.   value:.  Subclasses must implement:   
  6.   
  7.     accessing models   computeValue
  8.     
  9.     Instance Variables:   
  10.     
  11.     cachedValue     <Object>   
  12.     eagerEvaluation <Boolean> controls whether to wait until the 
  13.                               receiver is asked to perform the 
  14.                               computation (eager vs. late)
  15.  
  16.     Class Variables:   
  17.     
  18.     unassignedValue <Object> a unique object that is guaranteed to 
  19.                              be used by no one else in the system,
  20.     used to denote that the value has not yet been computedObject 
  21.  
  22.   Reference:
  23.     ComputedValue is an abstract class that provides support 
  24.     for creating a BlockClosure that recomputes a cached value
  25.   whenever one of the block arguments changes its value.  When asked 
  26.   for its #value, a ComputedValue supplies its cached value, 
  27.   recomputing it if necessary.  This is useful when object3 is 
  28.   computed using object1 and object2, which are expected to be 
  29.   value models.  ComputedValue has a single subclass, 
  30.   BlockValue.  For usage instructions, see BlockValue.  When creating 
  31.   a subclass, equip it with the following methods:
  32.  
  33.     parts       computeValue 
  34.     
  35.   Subclasses should not implement:    value:  
  36.   -------------------------------------------------------------------
  37. "
  38. Class ComputedValue :ValueModel 
  39. ! cachedValue eagerEvaluation unassignedValue !
  40. [
  41.    initialize
  42.       unassignedValue <- Object new.
  43.       cachedValue     <- unassignedValue.   
  44.       eagerEvaluation <- true 
  45. |
  46.    resetCache
  47.       cachedValue <- unassignedValue
  48. |
  49.    releaseParts   
  50.       " Remove any dependencies involving the receiver. "   
  51.       self parts do: [:m | m removeDependent: self]. 
  52. |  
  53.    eagerEvaluation: aBoolean    
  54.       " If aBoolean is true the receiver will do late evaluation of its
  55.       * computation; otherwise the receiver will do eager computation.
  56.       "   
  57.       eagerEvaluation <- aBoolean 
  58.    parts  " defined in BlockValue: " 
  59.       " Answer a collection of objects that have the receiver as a dependent. " 
  60.   
  61.       ^ self subclassResponsibility: 'parts'
  62.    value   
  63.       " Answer the cached value for the receiver. If the value is unknown,    
  64.       * then compute the value.
  65.       "   
  66.       (cachedValue == unassignedValue) 
  67.          ifTrue: [cachedValue <- self computeValue].   
  68.    
  69.       ^ cachedValue
  70.    value: anObject   
  71.       self shouldNotImplement 
  72. |  
  73.    update: aspect with: parameter from: sender    
  74.       " If a model is propogating a change, then reset the receiver and
  75.       * propogate change to dependents.
  76.       "   
  77.       self resetValue 
  78. |  
  79.    printOn: aStream   
  80.       " Print the receiver`s value on aStream. "   
  81.      
  82.       (cachedValue == unassignedValue) 
  83.         ifFalse: [^super printOn: aStream].   
  84.      
  85.       aStream print: self class.   
  86.       aStream nextPutAll: ' with: TheUnassignedValue'. 
  87. |
  88.    computeValue   
  89.       " Compute a value for the receiver. "   
  90.       ^ self subclassResponsibility: 'computeValue'
  91.    resetValue   
  92.       " Set the receiver`s value to unknown.  
  93.       * Propogate change to dependents.
  94.       "   
  95.       (eagerEvaluation = true)      
  96.          ifFalse: [cachedValue <- unassignedValue]      
  97.           ifTrue: [cachedValue <- self computeValue].   
  98.      
  99.       self changed: #value 
  100. ]
  101.